local jLootz = jLootz
local lib = jLootz:NewModule("Master", "AceEvent-3.0")

local function clear(table)
	while true do
		local k = next(table)
		if not k then break end
		table[k] = nil
	end
end

local GRAY = { r = 0.5, g = 0.5, b = 0.5 }
function lib:BuildCandidates()
	local candidates = self.candidates
	if not candidates then
		candidates = {}
		self.candidates = candidates
	else
		clear(candidates)
	end
	for i = 1, 40 do
		local c = GetMasterLootCandidate(i)
		if c then
			candidates[c] = i
		end
	end

	local units = self.units
	if not units then
		units = {}
		self.units = units
	else
		clear(units)
	end
	for i = 1, 40 do
		local unit = "raid"..i
		local name = UnitName(unit)
		if name and candidates[name] then
			units[name] = unit
		end
	end

	local classes = self.classes
	if not classes then
		classes = {}
		self.classes = classes
	else
		for _, units in pairs(classes) do
			clear(units)
		end
	end
	for candidate in pairs(candidates) do
		local unit = units[candidate]
		local class = unit and select(2, UnitClass(unit)) or "UNKNOWN"
		local cinfo = classes[class]
		if not cinfo then
			cinfo = {
				names = {},
				candidates = {},
			}
			classes[class] = cinfo
		end
		cinfo.names[UnitSex(unit)] = UnitClass(unit)
		cinfo.candidates[#cinfo + 1] = candidate
	end
end

local function spd_OnAccept (index)
	GiveMasterLoot(lib.slot, index)
end

function lib:OnEnable()
	if not jLootz_DONT_DISABLE_BASE_UI then
		LootFrame:UnregisterEvent("OPEN_MASTER_LOOT_LIST")
		LootFrame:UnregisterEvent("UPDATE_MASTER_LOOT_LIST")
	end
	self:RegisterEvent("OPEN_MASTER_LOOT_LIST")
	self:RegisterEvent("UPDATE_MASTER_LOOT_LIST")
	self.anchor = LootFrame.selectedLootButton
	self.slot = LootFrame.selectedSlot

	self.prev_spd_OnAccept = StaticPopupDialogs.CONFIRM_LOOT_DISTRIBUTION.OnAccept
	StaticPopupDialogs.CONFIRM_LOOT_DISTRIBUTION.OnAccept = spd_OnAccept
end

function lib:OnDisable()
	LootFrame:RegisterEvent("OPEN_MASTER_LOOT_LIST")
	LootFrame:RegisterEvent("UPDATE_MASTER_LOOT_LIST")
	StaticPopupDialogs.CONFIRM_LOOT_DISTRIBUTION.OnAccept = self.prev_spd_OnAccept
end

function lib:OPEN_MASTER_LOOT_LIST()
	self:BuildCandidates()
end

function lib:UPDATE_MASTER_LOOT_LIST()
	self:BuildCandidates()
end

function lib:SetTarget(anchor, slot)
	self.anchor = anchor
	self.slot = slot
end

function lib:GetCandidateName(index)
	if type(index) ~= "number" then
		index = assert(self.candidates and self.candidates[index])
	end
	local candidate = GetMasterLootCandidate(index)
	local unit = self.units[candidate]
	local color = RAID_CLASS_COLORS[select(2, UnitClass(unit))] or GRAY
	return ("|cff%2x%2x%2x%s|r"):format(color.r*255, color.g*255, color.b*255, candidate)
end

function lib:GiveMasterLoot(index)
	if not self.slot then return end
	if type(index) ~= "number" then
		index = assert(self.candidates and self.candidates[index])
	end

	local _, name, _, quality = GetLootSlotInfo(self.slot) -- @FIXME Use Confirm module
	if quality >= MASTER_LOOT_THREHOLD then
		local dialog = StaticPopup_Show("CONFIRM_LOOT_DISTRIBUTION", ITEM_QUALITY_COLORS[quality].hex..name..FONT_COLOR_CODE_CLOSE, self:GetCandidateName(index));
		if dialog then
			dialog.data = index
		end
	else
		GiveMasterLoot(self.slot, index)
	end
end
